﻿using System;
using System.Collections.Generic;
using System.Linq;
using SoftSource.Common;
using SoftSource.Reactive;
using SoftSource.Timecard.ViewModelInterfaces;
using SoftSource.Timecard.ViewModels;

namespace SoftSource.Timecard.Controller
{
    public sealed partial class ProjectManagerController
    {
        private static IMainViewModelService CreateMainViewModel()
        {
            IMainViewModelService vm = new MainViewModel();

            vm.CreateSummaryView = App.Controller.CreateSummaryView;
            vm.CreateManagementView = App.Controller.CreateManagementView;
            vm.CreateTimeEntryListView = App.Controller.CreateEntryManagementView;
            vm.CreateReportListView = App.Controller.CreateReportView;

            return vm;
        }

        private static IReportListViewModelService CreateReportViewModel()
        {
            IReportListViewModelService vm = new ReportListViewModel();

            vm.Load = App.Model.Reports.Load
                .Do(unit => vm.ReportCollection = App.Model.Reports.Entities);

            return vm;
        }

        private static IEntryManagementViewModelService CreateEntryManagementViewModel()
        {
            IEntryManagementViewModelService vm = new EntryManagementViewModel();

            var load = new List<IObservable<Unit>>();
            load.Add(App.Model.ProjectSummaries.Load);
            load.Add(App.Model.UserSummaries.Load);

            vm.Load = load
                .ForkJoin()
                .Do(units => vm.ProjectSource = App.Model.ProjectSummaries.Entities
                    .Where(project => project.ManagerUserID == WebContext.Current.User.UserID))
                .Do(units => vm.UserSource = App.Model.UserSummaries.Entities)
                .Once();

            vm.Refresh = (projectID, userID, startDate, endDate) =>
                App.Model
                .GetFilteredEntries(projectID, userID, startDate, endDate)
                .Do(entries => vm.EntrySource = entries.Enumerate())
                .Once();

            vm.SaveApprovals = App.Model.Entries.Save.ToUnit();
            vm.EditEntryAssociations = App.Controller.CreateEntryProjectCategoryAssociationEditorView;

            return vm;
        }

        private static ISummaryViewModelService CreateSummaryViewModel()
        {
            ISummaryViewModelService vm = new SummaryViewModel();

            vm.CreatePriorEntriesView = App.Controller.CreateEntriesPriorToProjectBillingDateView;
            vm.CreateUtilizationSummaryView = App.Controller.CreateUtilizationSummaryView;

            return vm;
        }

        private static IUtilizationSummaryViewModelService CreateUtilizationSummaryViewModel()
        {
            IUtilizationSummaryViewModelService vm = new UtilizationSummaryViewModel();

            vm.Load = App.Model.UserSummaries.Load
                .Do(unit => vm.UserSource = App.Model.UserSummaries.Entities
                    .Where(us => us.IsActive))
                .ToUnit()
                .Once();

            vm.LoadEntrySummaries = (start, end) => App.Model
                .GetUtilizationSummaries(start, end)
                .Do(entries => vm.EntrySource = entries.Enumerate())
                .ToUnit();

            return vm;
        }

        private static IEntriesPriorToProjectBillingDateViewModelService CreateEntriesPriorToProjectBillingDateViewModel()
        {
            IEntriesPriorToProjectBillingDateViewModelService vm = new EntriesPriorToProjectBillingDateViewModel();

            var load = from projects in App.Model.ProjectSummaries.Load
                           .Do(unit => vm.ProjectSource = App.Model.ProjectSummaries.Entities)
                       from entries in App.Model
                           .GetEntriesPriorToLastBillingDate()
                           .Do(entries => vm.EntrySource = entries)
                       select entries;

            vm.Load = load.Once();

            return vm;
        }
    }
}
